import java.util.Comparator;

public class PArgs {
    public PArgs(Object[] args) { this.args = args; }
    public Object get(int i) { return args[i]; }    
    public void set(int i, Object x) { args[i] = x; }
    public int count() { return args.length; }

    public String toString() {
        String s = "";
        for (int i = 0; i < args.length; ++i) {
            s += args[i] + (i + i < args.length ? ", " : " ");
        }  
        return s;
    }
    
    // Note: we don't have to worry about differently-sized
    //       argument lists since they have already been
    //       grouped together based on their size before
    //       they are ever compared.
    
    public int compare(PArgs other) {
        if (count() == 0) return true; 
        return (new PCmp()).compare(args[0], other.get(0));        
    }
    
    public boolean equal(PArgs other) {
        for (int i = 0; i < args.length; ++i) {
            if (compare(other.get(i)) != 0) return false;
        }
        return true;
    }
    
    public class PCmp implements Comparator<Object> {
        public int compare(Object p0, Object p1) {
            if (p0 instanceof Number) {
                if (p1 instanceof Number) {
                    return ((Integer) p0).intValue() - ((Integer) p1).intValue();
                }
                // All other patterns (at this moment) are more general than
                // constants.
                return true;
            }
            else if (p0 instanceof PVar) return p1 instanceof PVar; 
            else if (p0 instanceof PQuery) return p1 instanceof PQuery;
            return false;
        }    
         
        public boolean equal(Object p) {
            if (p0 instanceof Number) {
                return p1 instanceof Number &&
                    ((Integer) p0).intValue() == ((Integer) p1).intValue();
                }
            } else if (p0 instanceof PVar) {
                return p1 instanceof PVar && ((PVar) p0).sameVar((PVar) p1);
            } else if (p0 instanceof PQuery) return p0 == p1;
            return false;                       
        }

    public Object[] args;
}

  
